package com.shelpe.services.lexicon.service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.shelpe.services.lexicon.constants.Device;
import com.shelpe.services.lexicon.entity.AdgroupRecord;
import com.shelpe.services.lexicon.entity.KeywordRecommend;
import com.shelpe.services.lexicon.entity.WordInsightMetric;
import com.shelpe.services.lexicon.entity.metrics.InsightMetrics;
import com.shelpe.services.lexicon.properties.AutoDriveParams;
import com.shelpe.services.lexicon.properties.AutoDriveParams.Mode;
import com.shelpe.services.lexicon.repository.mongo.KeywordRecommendRepository;
import com.shelpe.services.lexicon.service.price.MobileRecommendPriceRule;
import com.shelpe.services.lexicon.service.price.PriceScoreRecommendPriceRule;
import com.shelpe.services.lexicon.service.price.RecommendPriceRuleContext;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class KeywordRecommendPriceService {

	@Autowired
	private PriceScoreRecommendPriceRule recommendPriceRule;
	
	@Autowired
	private MobileRecommendPriceRule mobileRecommendPriceRule;
	@Autowired
	private KeywordRecommendRepository keywordRecommendRepository;
	@Autowired
	private AutoDriveParams params;
	@Autowired
	private InsightMetricService insightMetricService;
	
	public void fetchPqr(String modeName, List<KeywordRecommend> recommends,  AdgroupRecord record, Device device){
		if(recommends != null){
			RecommendPriceRuleContext context = new RecommendPriceRuleContext();
			Mode mode = this.params.getModes().get(modeName);
			context.setMode(mode);
			List<WordInsightMetric> metrics = this.insightMetricService.findByAdgroupIDAndCategoryID(record.getAdgroupID(), 
					record.getRootCategoryID(), DateUtils.addDays(DateUtils.truncate(new Date(), Calendar.DATE), -1));
			context.setCategoryInsight(metrics.iterator().next());
			
			for(KeywordRecommend recommend: recommends){
				InsightMetrics insight = ((device == Device.mobile)?recommend.getMobileInsight():recommend.getInsight());
				if(insight == null){
					insight = InsightMetrics.BLANK_INSIGHT_METRIC;
				}
				if(device == Device.mobile){
					mobileRecommendPriceRule.performace(recommend, insight, context);
				}else{
					recommendPriceRule.performace(recommend, insight, context);
				}
			}
			log.debug("max performance: {}", context.getMaxPerformance());
			
			log.debug("start tp process similarity");
			for(KeywordRecommend recommend: recommends){
				InsightMetrics insight = ((device == Device.mobile)?recommend.getMobileInsight():recommend.getInsight());
				if(insight == null){
					insight = InsightMetrics.BLANK_INSIGHT_METRIC;
				}
				if(device == Device.mobile){
					mobileRecommendPriceRule.similarity(recommend, insight, context);
				}else{
					recommendPriceRule.similarity(recommend, insight, context);
				}
			}
			
			log.debug("start tp process pqr");
			for(KeywordRecommend recommend: recommends){
				InsightMetrics insight = ((device == Device.mobile)?recommend.getMobileInsight():recommend.getInsight());
				if(insight == null){
					insight = InsightMetrics.BLANK_INSIGHT_METRIC;
				}
				if(device == Device.mobile){
					mobileRecommendPriceRule.pqr(recommend, insight, context);
				}else{
					recommendPriceRule.pqr(recommend, insight, context);
				}
			}
			
			log.debug("store the update");
			for(KeywordRecommend recommend: recommends){
				recommend.setLastModifiedTime(new Date());
				this.keywordRecommendRepository.save(recommend);
			}
		}
	}
	
	
	public void fetchPrice(String modeName, List<KeywordRecommend> recommends,  AdgroupRecord record, Device device, int defaultPrice, int maxPrice){
		if(recommends != null){
			RecommendPriceRuleContext context = new RecommendPriceRuleContext();
			if(defaultPrice > 0){
				context.setDefaultPrice(defaultPrice);
			}
			if(maxPrice > 0){
				context.setMaxtPrice(maxPrice);
			}
			Mode mode = this.params.getModes().get(modeName);
			context.setMode(mode);
			
			//find the min and max score;
			for(KeywordRecommend recommend: recommends){
				InsightMetrics insight = ((device == Device.mobile)?recommend.getMobileInsight():recommend.getInsight());
				if(insight == null){
					insight = InsightMetrics.BLANK_INSIGHT_METRIC;
				}
				if(device == Device.mobile){
					mobileRecommendPriceRule.score(recommend, insight, context);
				}else{
					recommendPriceRule.score(recommend, insight, context);
				}
			}
			log.debug("max score: {}, min score: {}", context.getMaxScore(), context.getMinScore());
			
			//pricing
			for(KeywordRecommend recommend: recommends){
				InsightMetrics insight = ((device == Device.mobile)?recommend.getMobileInsight():recommend.getInsight());
				if(insight == null){
					insight = InsightMetrics.BLANK_INSIGHT_METRIC;
				}
				if(device == Device.mobile){
					mobileRecommendPriceRule.price(recommend, insight, context);
				}else{
					recommendPriceRule.price(recommend, insight, context);
				}
			}
			
			for(KeywordRecommend recommend: recommends){
				recommend.setLastModifiedTime(new Date());
			}
			this.keywordRecommendRepository.save(recommends);
		}
	}
	
}
